//引入Threejs
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/Addons.js";
//导入字体加载器
import { FontLoader } from "three/addons/loaders/FontLoader.js";
//引入字体几何体
import { TextGeometry } from "three/addons/geometries/TextGeometry.js";

//画布大小
const size = {
  width: window.innerWidth,
  height: window.innerHeight,
};

window.addEventListener("resize", () => {
  size.width = window.innerWidth;
  size.height = window.innerHeight;

  //相机
  camera.aspect = size.width / size.height;
  camera.updateProjectionMatrix();

  renderer.setSize(size.width, size.height);
});

/*
  纹理
*/
const textureLoader = new THREE.TextureLoader();
const matcapsTexture = textureLoader.load("/src/assets/textures/matcaps/7.png");
/*
  Fonts
*/
//创建字体加载器实例
const treeLoader = new FontLoader();
//加载字体
treeLoader.load(
  "/src/assets/fonts/helvetiker_regular.typeface.json",
  (fontRes) => {
    //创建字体几何体
    const geometry = new TextGeometry("Hello Upsilon!", {
      //要使用的字体样式，我们用加载成功的字体
      font: fontRes,
      //Float. Size of the text. Default is 100.
      //字体的大小
      size: 0.5,
      // Float. Thickness to extrude text. Default is 50.
      //字体的深度
      depth: 0.2,
      //Integer. Number of points on the curves. Default is 12.
      //字体曲线
      curveSegments: 6,
      //Boolean. Turn on bevel. Default is False.
      //是否启用斜面效果
      bevelEnabled: true,
      //Float. How deep into text bevel goes. Default is 10.
      //斜角厚度
      bevelThickness: 0.03,
      // Float. How far from text outline is bevel. Default is 8.
      //斜角尺寸
      bevelSize: 0.02,
      //Float. How far from text outline bevel starts. Default is 0.
      //斜角偏移
      bevelOffset: 0,
      // Integer. Number of bevel segments. Default is 3.
      //斜角分段
      bevelSegments: 3,
    });

    /* 居中方法1：使用包围盒 */
    //开启盒子bounding
    // geometry.computeBoundingBox();
    // console.log(geometry.boundingBox);

    // geometry.translate(
    //   -(geometry.boundingBox.max.x - 0.02) * 0.5,
    //   -(geometry.boundingBox.max.y - 0.02) * 0.5,
    //   -(geometry.boundingBox.max.z - 0.03) * 0.5
    // );

    /* 居中方法2:使用文字几何体的居中方法 */
    geometry.center();

    //创建材质
    const material = new THREE.MeshMatcapMaterial({ matcap: matcapsTexture });
    // material.wireframe = true;
    //创建网格
    const textCube = new THREE.Mesh(geometry, material);

    //把网格加入场景中
    scene.add(textCube);
  }
);

//创建一个场景
const scene = new THREE.Scene();

console.time("start");
/* 加入甜甜圈 */
const donutGeometry = new THREE.TorusGeometry(0.3, 0.2, 20, 45);
const donutMaterial = new THREE.MeshMatcapMaterial({
  matcap: matcapsTexture,
});
for (let i = 0; i < 100; i++) {
  const donut = new THREE.Mesh(donutGeometry, donutMaterial);

  //减去0.5，是为了分布在左右两边，而不是都集中在一边
  donut.position.x = (Math.random() - 0.5) * 10;
  donut.position.y = (Math.random() - 0.5) * 10;
  donut.position.z = (Math.random() - 0.5) * 10;

  donut.rotation.x = Math.random() * Math.PI;
  donut.rotation.y = Math.random() * Math.PI;

  const scaleVal = Math.random();
  donut.scale.x = scaleVal;
  donut.scale.y = scaleVal;
  donut.scale.z = scaleVal;
  scene.add(donut);
}
console.timeEnd("start");
/* 相机 */
const camera = new THREE.PerspectiveCamera(
  55,
  size.width / size.height,
  0.1,
  1000
);

camera.position.z = 5;
camera.position.x = -3;

// camera.lookAt(mesh.position);
scene.add(camera);

/* 渲染器 */
const renderer = new THREE.WebGLRenderer();
renderer.setSize(size.width, size.height);
renderer.domElement.setAttribute("class", "my-canvas");
document.body.appendChild(renderer.domElement);

/* 控制器 */
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

const clock = new THREE.Clock();

/* 轴辅助器 */
// const axis = new THREE.AxesHelper(10);
// scene.add(axis);

const change = () => {
  const elapsedTime = clock.getElapsedTime();

  controls.update();

  renderer.render(scene, camera);
  requestAnimationFrame(change);
};

change();
